import { join } from 'path';
import { createClient, RedisClient } from 'redis';

// tslint:disable-next-line:no-var-requires
const config = require(join(process.cwd(), './feidao.json')) as {
	REDIS: {
		URL: string;
		EXPIRATION: number;
	};
};

const REDIS = config.REDIS;

export function open() {
	return createClient(REDIS.URL);
}

export function close(client: RedisClient) {
	// return client.quit();
	return client.end(true);
}

/*
 * Set the value of a key.
 */
export function set(client: RedisClient, key: string, value: any) {
	return new Promise<string>((resolve, reject) => {
		const v = JSON.stringify(value);
		// EX seconds PX milliseconds NX XX	https://redis.io/commands/set
		client.set(key, v, 'EX', REDIS.EXPIRATION, (error, res) => {
			if (error) {
				reject(error);
			} else {
				resolve(res);
			}
		});
	});
}

/**
 * Get the value of a key.
 */
export function get<T = string>(client: RedisClient, key: string) {
	return new Promise<T | null>((resolve, reject) => {
		// client.expire(key, REDIS.EXPIRATION);	// ? Do we need this?
		client.get(key, (error, res) => {
			if (error) {
				reject(error);
			} else {
				if (res === undefined || res === 'undefined' || res === null) {
					resolve(null);
				} else {
					resolve(JSON.parse(res));
				}
			}
		});
	});
}

/**
 * Delete a key.
 */
export function remove(client: RedisClient, key: string | string[]) {
	return new Promise<number>((resolve, reject) => {
		return client.del(key, (error, res) => {
			if (error) {
				reject(error);
			} else {
				resolve(res);
			}
		});
	});
}

/**
 * Set a key's time to live in seconds.
 */
export function expire(client: RedisClient, key: string, seconds: number) {
	return new Promise<number>((resolve, reject) => {
		return client.expire(key, seconds, (error, res) => {
			if (error) {
				reject(error);
			} else {
				resolve(res);
			}
		});
	});
}
